package se.webbzon.boltzmann.game.event;

import java.util.Collection;

import se.webbzon.boltzmann.game.object.camera.GameCamera;
import se.webbzon.boltzmann.game.object.player.AbstractPlayerCharacter;
import se.webbzon.boltzmann.game.sequence.Sequence;
import se.webbzon.boltzmann.game.sequence.builder.AbstractSequenceBinding;
import se.webbzon.oschi01.worldarea.WorldArea;
import se.webbzon.oschi01.worldobject.WorldObject;
import se.webbzon.oschi01.worldobject.WorldStaticObject;

public class SetGameCameraTargetEvent extends AbstractTargetEvent {
	
	// Whatever all game cameras should be set
	private final boolean all;
	
	// Whatever the game cameras should reset
	private final boolean reset;
	
	/*============================================================
	Constructors
	============================================================*/
	
	public SetGameCameraTargetEvent(Sequence sequence, String[] arguments, boolean all, boolean reset) {
		super(sequence,arguments);
		this.all = all;
		this.reset = reset;
	}
	
	/*============================================================
	Public Methods
	============================================================*/

	@Override protected void onBegin(WorldArea world) {
		Collection<GameCamera> gameCameras = world.findInstances(GameCamera.class);
		WorldStaticObject target;
		WorldObject t = getTarget();
		if (!reset && t instanceof WorldStaticObject)
			target = (WorldStaticObject) t;
		else
			target = null;
		
		if (all)
			setAll(gameCameras,target);
		else
			setSingle(gameCameras,target);
		end();
	}

	@Override protected void onEnd() {};
	
	/*============================================================
	Private Methods
	============================================================*/
	
	/** Sets or resets the target of the game camera for the player associated 
	 * with this sequence of this event. **/
	private final void setSingle(Collection<GameCamera> gameCameras, WorldStaticObject target) {
		WorldObject wo = getSequence().getBinding(AbstractSequenceBinding.PLAYER);
		if (wo instanceof AbstractPlayerCharacter) {
			AbstractPlayerCharacter player = (AbstractPlayerCharacter) wo;
			for (GameCamera camera : gameCameras) {
				if (camera.getPlayer() == player.getPlayer()) {
					if (target == null)
						camera.setTarget(player);
					else
						camera.setTarget(target);
					return;
				}
			}
		}
	}
	
	/** Sets or resets the target of all game cameras. **/
	private final void setAll(Collection<GameCamera> gameCameras, WorldStaticObject target) {
		if (target == null) {
			Collection<AbstractPlayerCharacter> players;
			players = getSequence().getWorld().findInstances(AbstractPlayerCharacter.class);
			for (GameCamera camera : gameCameras) {
				for (AbstractPlayerCharacter player : players) {
					if (player.getPlayer() == camera.getPlayer())
						camera.setTarget(player);
				}
			}
		} else {
			for (GameCamera c : gameCameras)
				c.setTarget(target);
		}
	}
	
}
